﻿/*!
* jQuery Extensions JavaScript Library v1.0.0
* http://solutiongear.net/
*
* Copyright 2012, Ralph Luo
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://solutiongear.net/RapidForm/license
*
* Includes rapidform.js
* Copyright 2012, The Xiamen SHENGUAN Software Technology Co., Ltd.
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: 2012-03-06 14:20:10 
*/

(function ($) {
    //TODO:定宽输出
    //Description:把已传入值格式化为指定长度的定宽字段。如果数值超过指定长度，数值的高位数字符将被截断以便符合指定的长度
    //value:(Number)传入值; length:(Number)指定长度; fill:(String)填充字符
    //return:(String)定宽字段
    $.toFixedWidth = function (value, length, fill) {
        var result = value.toString();
        if (!fill) fill = '0';
        var padding = length - result.length;
        if (padding < 0) {
            result = result.substr(-padding);
        } else {
            for (var n = 0; n < padding; n++)
                result = fill + result;
        }
        return result;
    };

    //TODO:日期格式器
    //Description:对已传入日期根据提供的模式进行格式化
    //date:(Date)将被格式化的日期; pattern:(String)用来对日期进行格式化的模式。不匹配模式标记的任何字符将被原样的复制到结果中
    //return:(String)已经格式化的日期
    /*  pattern说明
    yyyy: 4位年数
    yy:   2位年数
    MM:   2位月份数，不足两位左边补0
    M:    月份数
    dd:   2位天数，不足两位左边补0
    d:    天数
    EEEE: 星期数
    a:    上午或者下午
    HH:   24小时制的2位小时数，不足两位左边补0
    H:    24小时制的小时数
    hh:   12小时制的2位小时数，不足两位左边补0
    h:    12小时制的小时数
    mm:   2位的分钟数，不足两位左边补0
    m:    分钟数
    ss:   2位的秒数，不足两位左边补0
    s:    秒数
    S:    毫秒数，3个字符的字段，不足3个字符左边补0

    示例： 
    var d = new Date(2012, 2, 6, 12, 13, 14, 50);
    alert($.formatDate(d, 'yyyy-MM-dd HH:mm:ss S EEEE a');)
    输出：‘2012-03-06 12:13:14 050 星期二 下午’
    */
    $.formatDate = function (date, pattern) {
        var result = [];
        while (pattern.length > 0) {
            $.formatDate.patternParts.lastIndex = 0;
            var matched = $.formatDate.patternParts.exec(pattern);
            if (matched) {
                result.push($.formatDate.patternValue[matched[0]].call(this, date));
                pattern = pattern.slice(matched[0].length);
            }
            else {
                result.push(pattern.charAt(0));
                pattern = pattern.slice(1);
            }
        }
        return result.join('');
    };

    $.formatDate.patternParts =
    /^(yy(yy)?|M(M(M(M)?)?)?|d(d)?|EEE(E)?|a|H(H)?|h(h)?|m(m)?|s(s)?|S)/;

    $.formatDate.monthNames = [
    'January', 'February', 'March', 'April', 'May', 'June', 'July',
    'August', 'September', 'October', 'November', 'December'
  ];

    $.formatDate.dayNames = [
    //'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
    //'Saturday'
    '星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'
  ];

    $.formatDate.patternValue = {
        yy: function (date) {
            return $.toFixedWidth(date.getFullYear(), 2);
        },
        yyyy: function (date) {
            return date.getFullYear().toString();
        },
        MMMM: function (date) {
            return $.formatDate.monthNames[date.getMonth()];
        },
        MMM: function (date) {
            return $.formatDate.monthNames[date.getMonth()].substr(0, 3);
        },
        MM: function (date) {
            return $.toFixedWidth(date.getMonth() + 1, 2);
        },
        M: function (date) {
            return date.getMonth() + 1;
        },
        dd: function (date) {
            return $.toFixedWidth(date.getDate(), 2);
        },
        d: function (date) {
            return date.getDate();
        },
        EEEE: function (date) {
            return $.formatDate.dayNames[date.getDay()];
        },
        EEE: function (date) {
            return $.formatDate.dayNames[date.getDay()].substr(0, 3);
        },
        HH: function (date) {
            return $.toFixedWidth(date.getHours(), 2);
        },
        H: function (date) {
            return date.getHours();
        },
        hh: function (date) {
            var hours = date.getHours();
            return $.toFixedWidth(hours > 12 ? hours - 12 : hours, 2);
        },
        h: function (date) {
            return date.getHours() % 12;
        },
        mm: function (date) {
            return $.toFixedWidth(date.getMinutes(), 2);
        },
        m: function (date) {
            return date.getMinutes();
        },
        ss: function (date) {
            return $.toFixedWidth(date.getSeconds(), 2);
        },
        s: function (date) {
            return date.getSeconds();
        },
        S: function (date) {
            return $.toFixedWidth(date.getMilliseconds(), 3);
        },
        a: function (date) {
            //return date.getHours() < 12 ? 'AM' : 'PM';
            return date.getHours() < 12 ? '上午' : '下午';
        }
    };

    //TODO:字符串格式器
    //Description:对已传入带有占位符的字符串进行格式化
    //arguments[0]:(String)将被格式化的字符串; arguments[n](n>0):(String)用来对字符串进行格式化的参数。参数按照前后顺序对应到占位符
    //return:(String)已经格式化的字符串
    /*
    字符串拼接，类似C# string.Format()
    示例： 
    var uid = 'admin';
    var pwd = '123';
    var str = Format("username={0} and password ={1}", uid, pwd);
    alert(str); 
    //输出结果： 'username=admin and password =123'
    */
    $.formatString = function () {
        if (arguments.length < 2) {
            throw new Error('formatString方法的参数至少两个');
        }
        var counter = arguments[0].match(/\{\d\}/g).length;
        if (counter < arguments.length - 1) {
            throw new Error('formatString方法的参数数量错误');
        }
        var patt;
        for (var i = 0; i < arguments.length - 1; i++) {
            patt = new RegExp("\\{" + i + "\\}", "g");
            if (!patt.test(arguments[0])) {
                throw new Error("formatString方法中索引为 " + (i + 1) + " 的参数无替换对象");
            }
            arguments[0] = arguments[0].replace(patt, arguments[i + 1]);
        }
        return arguments[0];
    }

    //TODO:删除数组中重复元素
    //Description:函数通过搜索数组元素，排序数组，并移除任何重复的元素
    //val:(Array)需要处理的数组
    //return:(Array)已经删除重复元素的数组
    $.uniqueArray = function (val) {
        val = val || [];
        var a = {};
        for (var i = 0; i < val.length; i++) {
            var v = val[i];
            if (typeof (a[v]) == 'undefined') {
                a[v] = 1;
            }
        };
        val.length = 0;
        for (var i in a) {
            //排除A的function成员
            if (typeof a[i] != 'function') {
                val[val.length] = i;
            }
        }
        return val;
    }

    //************************************************************************
    //TODO:关闭当前窗口
    //Description:适用于IE6+，Chrome, Fiefox，Safari等主流浏览器
    //msg:(String)执行关闭前的提示信息
    //return:
    //$.closeCurrentWindow = function (msg, fn) {
//        if (confirm(msg == null ? '确认关闭当前窗口？' : msg)) {
//            if (fn) {
//                fn();
//            }
//            var opened = window.open('about:blank', '_self');
//            opened.opener = null;
//            opened.close();
//        }

    $.closeCurrentWindow = function () {
        var opened = window.open('about:blank', '_self');
        opened.opener = null;
        opened.close();
    }

    //************************************************************************
    //TODO:把字符串类型转成日期类型
    //Description:控件存取值时候转换用
    //dateString:(String)字符串日期
    //formatString:(string)日期进行格式化的模式
    $.convertDateToString = function (dateString, formatString) {
        if ($.validateDate(dateString, formatString)) {
            var now = new Date();
            var vals = $.convertDateToString.regexp.exec(dateString);
            var index = $.validateIndex(formatString);
            var year = index[0] >= 0 ? vals[index[0] + 1] : now.getFullYear();
            var month = index[1] >= 0 ? (vals[index[1] + 1] - 1) : now.getMonth();
            var day = index[2] >= 0 ? vals[index[2] + 1] : now.getDate();
            var hour = index[3] >= 0 ? vals[index[3] + 1] : "";
            var minute = index[4] >= 0 ? vals[index[4] + 1] : "";
            var second = index[5] >= 0 ? vals[index[5] + 1] : "";

            var validate;

            if (hour == "")
                validate = new Date(year, month, day);
            else
                validate = new Date(year, month, day, hour, minute, second);

            if (validate.getDate() == day) return validate;

        }
        alert("wrong date");
    }

    $.convertDateToString.patternParts = {};
    /** year : /yyyy/ */
    $.convertDateToString.patternParts.y4 = "([0-9]{4})";
    /** year : /yy/ */
    $.convertDateToString.patternParts.y2 = "([0-9]{2})";
    /** index year */
    $.convertDateToString.patternParts.yi = -1;

    /** month : /MM/ */
    $.convertDateToString.patternParts.M2 = "(0[1-9]|1[0-2])";
    /** month : /M/ */
    $.convertDateToString.patternParts.M1 = "([1-9]|1[0-2])";
    /** index month */
    $.convertDateToString.patternParts.Mi = -1;

    /** day : /dd/ */
    $.convertDateToString.patternParts.d2 = "(0[1-9]|[1-2][0-9]|30|31)";
    /** day : /d/ */
    $.convertDateToString.patternParts.d1 = "([1-9]|[1-2][0-9]|30|31)";
    /** index day */
    $.convertDateToString.patternParts.di = -1;

    /** hour : /HH/ */
    $.convertDateToString.patternParts.H2 = "([0-1][0-9]|20|21|22|23)";
    /** hour : /H/ */
    $.convertDateToString.patternParts.H1 = "([0-9]|1[0-9]|20|21|22|23)";
    /** index hour */
    $.convertDateToString.patternParts.Hi = -1;

    /** minute : /mm/ */
    $.convertDateToString.patternParts.m2 = "([0-5][0-9])";
    /** minute : /m/ */
    $.convertDateToString.patternParts.m1 = "([0-9]|[1-5][0-9])";
    /** index minute */
    $.convertDateToString.patternParts.mi = -1;

    /** second : /ss/ */
    $.convertDateToString.patternParts.s2 = "([0-5][0-9])";
    /** second : /s/ */
    $.convertDateToString.patternParts.s1 = "([0-9]|[1-5][0-9])";
    /** index month */
    $.convertDateToString.patternParts.si = -1;

    //var regexp;
    $.convertDateToString.regexp;

    //验证日期格式是否有效
    $.validateDate = function (dateString, formatString) {
        var dateString = $.trim(dateString);
        if (dateString == "") return;
        var reg = formatString;
        reg = reg.replace(/yyyy/, $.convertDateToString.patternParts.y4);
        reg = reg.replace(/yy/, $.convertDateToString.patternParts.y2);
        reg = reg.replace(/MM/, $.convertDateToString.patternParts.M2);
        reg = reg.replace(/M/, $.convertDateToString.patternParts.M1);
        reg = reg.replace(/dd/, $.convertDateToString.patternParts.d2);
        reg = reg.replace(/d/, $.convertDateToString.patternParts.d1);
        reg = reg.replace(/HH/, $.convertDateToString.patternParts.H2);
        reg = reg.replace(/H/, $.convertDateToString.patternParts.H1);
        reg = reg.replace(/mm/, $.convertDateToString.patternParts.m2);
        reg = reg.replace(/m/, $.convertDateToString.patternParts.m1);
        reg = reg.replace(/ss/, $.convertDateToString.patternParts.s2);
        reg = reg.replace(/s/, $.convertDateToString.patternParts.s1);
        reg = new RegExp("^" + reg + "$");
        $.convertDateToString.regexp = reg;
        return reg.test(dateString);
    }

    $.validateIndex = function (formatString) {
        var ia = new Array();
        var i = 0;
        $.convertDateToString.patternParts.yi = formatString.search(/yyyy/);
        if ($.convertDateToString.patternParts.yi < 0) $.convertDateToString.patternParts.yi = formatString.search(/yy/);
        if ($.convertDateToString.patternParts.yi >= 0) {
            ia[i] = $.convertDateToString.patternParts.yi;
            i++;
        }

        $.convertDateToString.patternParts.Mi = formatString.search(/MM/);
        if ($.convertDateToString.patternParts.Mi < 0) $.convertDateToString.patternParts.Mi = formatString.search(/M/);
        if ($.convertDateToString.patternParts.Mi >= 0) {
            ia[i] = $.convertDateToString.patternParts.Mi;
            i++;
        }

        $.convertDateToString.patternParts.di = formatString.search(/dd/);
        if ($.convertDateToString.patternParts.di < 0) $.convertDateToString.patternParts.di = formatString.search(/d/);
        if ($.convertDateToString.patternParts.di >= 0) {
            ia[i] = $.convertDateToString.patternParts.di;
            i++;
        }

        $.convertDateToString.patternParts.Hi = formatString.search(/HH/);
        if ($.convertDateToString.patternParts.Hi < 0) $.convertDateToString.patternParts.Hi = formatString.search(/H/);
        if ($.convertDateToString.patternParts.Hi >= 0) {
            ia[i] = $.convertDateToString.patternParts.Hi;
            i++;
        }

        $.convertDateToString.patternParts.mi = formatString.search(/mm/);
        if ($.convertDateToString.patternParts.mi < 0) $.convertDateToString.patternParts.mi = formatString.search(/m/);
        if ($.convertDateToString.patternParts.mi >= 0) {
            ia[i] = $.convertDateToString.patternParts.mi;
            i++;
        }

        $.convertDateToString.patternParts.si = formatString.search(/ss/);
        if ($.convertDateToString.patternParts.si < 0) $.convertDateToString.patternParts.si = formatString.search(/s/);
        if ($.convertDateToString.patternParts.si >= 0) {
            ia[i] = $.convertDateToString.patternParts.si;
            i++;
        }

        var ia2 = new Array($.convertDateToString.patternParts.yi, $.convertDateToString.patternParts.Mi, $.convertDateToString.patternParts.di,
            $.convertDateToString.patternParts.Hi, $.convertDateToString.patternParts.mi, $.convertDateToString.patternParts.si);

        for (i = 0; i < ia.length - 1; i++)
            for (j = 0; j < ia.length - 1 - i; j++)
                if (ia[j] > ia[j + 1]) {
                    temp = ia[j];
                    ia[j] = ia[j + 1];
                    ia[j + 1] = temp;
                }

        for (i = 0; i < ia.length; i++)
            for (j = 0; j < ia2.length; j++)
                if (ia[i] == ia2[j]) {
                    ia2[j] = i;
                }

        return ia2;
    }

    //************************************************************************ 
    //TODO:把字符串类型转成自定义类型
    //Description:控件取值时候转换用
    //value:(String)字符串值
    //typeName:(string)类型名称 'Boolean','Number','Date'
    $.convertStringToCustomType = function (value, targetType) {
        if (value == null) {
            return null;
        }
        //从lable取非字符串值
        if (value == '' && targetType != 'String') {
            return null;
        }

        //默认是字符串类型 
        if (targetType == null) {
            targetType = 'String';
        }
        var result;
        switch (targetType) {
            case 'Boolean': result = $.convertStringToCustomType.convertStringToBoolean(value); break;
            case 'Number': result = Number(value); break;
            case 'Date': result = $.convertDateToString(value, 'yyyy-MM-dd HH:mm:ss'); break;
            case 'String': result = value; break;
            default: throw new Error('类型名称错误！'); break;
        }
        return result;
    }
    //TODO:把字符串类型转成布尔类型
    //Description:控件取值时候转换用
    //value:(String)字符串值
    $.convertStringToCustomType.convertStringToBoolean = function (str) {
        if (str.toLowerCase() == 'true' || str.toLowerCase() == '1') {
            return true;
        } else if (str.toLowerCase() == 'false' || str.toLowerCase() == '0') {
            return false;
        } else {
            return Boolean(str);
        }
    }

    //************************************************************************ 
    //TODO:把自定义类型转成字符串类型
    //Description:控件显示值时候转换用
    //value:(String)自定义类型值
    //typeName:(string)类型名称 'Boolean','Number','Date','String'
    $.convertCustomTypeToString = function (value, selfType) {
        if (value == null) {
            return null;
        }
        //默认是字符串类型
        if (selfType == null) {
            selfType = 'String';
        }
        var result;
        switch (selfType) {
            case 'Boolean':
            case 'Number': result = value.toString(); break;
            case 'Date':
                //如果日期是最小值,返回null
                if ($.formatDate(value, 'yyyy-MM-dd HH:mm:ss') == '1900-01-01 00:00:00') {
                    return null;
                }
                result = $.formatDate(value, 'yyyy-MM-dd HH:mm:ss'); break;
            case 'String': result = value; break;
            default: throw new Error('类型名称错误！'); break;
        }
        return result;
    }

    //************************************************************************ 
    //TODO:生成新的Guid值
    //Description:为新增记录生成Keyid值
    //example: var keyid = $.newGuid(); alert(keyid); 结果显示: '3911D7C7-404C-387A-A683-7F9ED5AAE894'
    //Return:返回字符串类型
    $.newGuid = function () {
        return ($.newGuid.newPartOfGuid() + $.newGuid.newPartOfGuid() + "-" + $.newGuid.newPartOfGuid() + "-" + $.newGuid.newPartOfGuid() + "-" + $.newGuid.newPartOfGuid() + "-"
            + $.newGuid.newPartOfGuid() + $.newGuid.newPartOfGuid() + $.newGuid.newPartOfGuid()).toUpperCase();
    }
    $.newGuid.newPartOfGuid = function () {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }

    //************************************************************************ 


})(jQuery);